package com.ruoyi.order.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ruoyi.common.config.wxpay.WxPayConfig;
import com.ruoyi.common.config.wxpay.pojo.JsApiOrderModel;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.core.domain.model.AppUserSnapshootDTO;
import com.ruoyi.common.core.domain.model.LoginAppUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.mqtt.ImmediateSender;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.OrderIdGenerator;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.order.domain.OrderInfo;
import com.ruoyi.order.domain.dto.OrderInfoAppPageDTO;
import com.ruoyi.order.domain.dto.OrderInfoDTO;
import com.ruoyi.order.domain.dto.OrderInfoPageDTO;
import com.ruoyi.order.domain.dto.OrderInfoSnapshotDTO;
import com.ruoyi.order.domain.vo.*;
import com.ruoyi.order.enums.OrderStatusAppEnum;
import com.ruoyi.order.enums.OrderStatusEnum;
import com.ruoyi.order.mapper.OrderInfoMapper;
import com.ruoyi.order.service.IOrderInfoService;
import com.ruoyi.server.domain.ServerTask;
import com.ruoyi.server.domain.dto.ServerTaskSnapshootDTO;
import com.ruoyi.server.domain.vo.ServerTaskPeopleCountVO;
import com.ruoyi.server.domain.vo.ServerTaskVO;
import com.ruoyi.server.enums.TaskStateEnum;
import com.ruoyi.server.service.IServerTaskService;
import com.ruoyi.user.domain.AppUserAccount;
import com.ruoyi.user.domain.dto.AppUserAccountSnapshootDTO;
import com.ruoyi.user.service.IAppUserAccountService;
import com.ruoyi.user.service.IAppUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 订单Service业务层处理
 *
 * @author ghostmen
 * @date 2024-11-03
 */
@Slf4j
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements IOrderInfoService {

    @Resource
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private IServerTaskService serverTaskService;
    @Autowired
    private IAppUserAccountService appUserAccountService;
    @Autowired
    private IAppUserService appUserService;
//    @Autowired
//    private ImmediateSender sendMsg;
    @Autowired
    private WxPayConfig wxPayConfig;
//    @Autowired
//    private Redisson redisson;

    //订单超时时间
    @Value("${custom.order.orderTimeOut}")
    private Integer orderTimeOut;

    /**
     * 查询订单
     *
     * @param orderId 订单主键
     * @return 订单
     */
    @Override
    public OrderInfoDetailsVO selectOrderInfoByOrderId(Long orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectOrderInfoByOrderId(orderId);
        if (Objects.isNull(orderInfo)) {
            return null;
        }
        OrderInfoDetailsVO orderInfoVO = BeanUtil.copyProperties(orderInfo, OrderInfoDetailsVO.class);
        orderInfoVO.setOrderStatusName(OrderStatusEnum.getOrderStatusEnumByCode(orderInfoVO.getOrderStatus()).getDescription());
        String orderSnapshot = orderInfo.getOrderSnapshot();
        OrderInfoSnapshotDTO orderInfoSnapshotDTO = JSON.parseObject(orderSnapshot, OrderInfoSnapshotDTO.class);
        orderInfoVO.setOrderInfoSnapshot(orderInfoSnapshotDTO);
        orderInfoVO.setPassword(orderInfoSnapshotDTO.getAccountSnapshoot().getPassword());
        return orderInfoVO;
    }

    /**
     * 查询订单
     *
     * @param orderId 订单主键
     * @return 订单
     */
    @Override
    public OrderInfoAppDetailsVO getInfoByOrderId(Long orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectOrderInfoByOrderId(orderId);
        if (Objects.isNull(orderInfo)) {
            return null;
        }
        OrderInfoAppDetailsVO orderInfoDetailsVO = BeanUtil.copyProperties(orderInfo, OrderInfoAppDetailsVO.class);
        OrderInfoSnapshotDTO orderInfoSnapshot = JSON.parseObject(orderInfo.getOrderSnapshot(), OrderInfoSnapshotDTO.class);
        orderInfoDetailsVO.setOrderInfoSnapshot(orderInfoSnapshot);
        return orderInfoDetailsVO;
    }

    @Override
    public OrderInfoAppDetailsVO getInfoByOrderNum(String orderNum) {
        OrderInfo orderInfo = orderInfoMapper.getOrderInfoByOrderNum(orderNum);
        if (Objects.isNull(orderInfo)) {
            return null;
        }
        OrderInfoAppDetailsVO orderInfoDetailsVO = BeanUtil.copyProperties(orderInfo, OrderInfoAppDetailsVO.class);
        orderInfoDetailsVO.setOrderStatusName(OrderStatusEnum.getOrderStatusEnumByCode(orderInfoDetailsVO.getOrderStatus()).getDescription());
        OrderInfoSnapshotDTO orderInfoSnapshot = JSON.parseObject(orderInfo.getOrderSnapshot(), OrderInfoSnapshotDTO.class);
        orderInfoDetailsVO.setOrderInfoSnapshot(orderInfoSnapshot);

        ServerTaskVO serverTaskVO = serverTaskService.selectServerTaskByTaskId(orderInfoDetailsVO.getTaskId());
        if (!Objects.isNull(serverTaskVO)) {
            orderInfoDetailsVO.setTaskName(serverTaskVO.getTaskName());
            orderInfoDetailsVO.setTaskState(serverTaskVO.getState());
            orderInfoDetailsVO.setTaskStateName(TaskStateEnum.getByCodeToApp(serverTaskVO.getState()));
        }

        return orderInfoDetailsVO;
    }

    /**
     * 查询订单列表
     *
     * @param pageDTO 订单
     * @return 订单
     */
    @Override
    public PageInfo<OrderInfoVO> selectOrderInfoList(OrderInfoPageDTO pageDTO) {
        if (null != pageDTO.getOrderStatus()) {
            Boolean exist = OrderStatusAppEnum.isExist(pageDTO.getOrderStatus());
            if (!exist) {
                throw new ServiceException("非法的订单状态类型");
            }
            pageDTO.setOrderStatusCode(OrderStatusEnum.getOrderStatusEnum(OrderStatusAppEnum.getOrderStatusEnumByCode(pageDTO.getOrderStatus())));
        }
        List<OrderInfo> orderInfoList = orderInfoMapper.selectOrderInfoList(pageDTO);
        if (CollectionUtils.isEmpty(orderInfoList)) {
            return new PageInfo<>();
        }
        PageInfo<OrderInfo> pageInfo = new PageInfo<>(orderInfoList);
        PageInfo<OrderInfoVO> voPageInfo = new PageInfo<>();
        List<OrderInfoVO> voList = pageInfo.getList().stream().map(orderInfo -> {
            OrderInfoVO orderInfoVO = new OrderInfoVO();
            BeanUtils.copyProperties(orderInfo, orderInfoVO);
            return orderInfoVO;
        }).collect(Collectors.toList());
        //  设置新的列表和总数
        voPageInfo.setList(voList);
        voPageInfo.setTotal(pageInfo.getTotal());

        // 复制其他分页信息
        voPageInfo.setPageNum(pageInfo.getPageNum());
        voPageInfo.setPageSize(pageInfo.getPageSize());
        voPageInfo.setSize(pageInfo.getSize());

        List<OrderInfoVO> orderInfoVOList = voPageInfo.getList();
        Map<Long, String> stringMap = orderInfoList.stream().collect(Collectors.toMap(OrderInfo::getOrderId, OrderInfo::getOrderSnapshot));
        List<Long> taskIds = orderInfoVOList.stream().map(OrderInfoVO::getTaskId).collect(Collectors.toList());
        List<ServerTask> serverTaskList = serverTaskService.selectServerTaskByTaskIds(taskIds);
        List<Long> userIds = orderInfoVOList.stream().map(OrderInfoVO::getOrderUserId).collect(Collectors.toList());
        List<AppUser> appUserList = appUserService.selectAppUserByUserIds(userIds);
        Map<Long, AppUser> userMap = appUserList.stream().collect(Collectors.toMap(AppUser::getUserId, appUser -> appUser, (k1, k2) -> k1));
        if (CollectionUtils.isNotEmpty(serverTaskList)) {
            Map<Long, ServerTask> taskMap = serverTaskList.stream().collect(Collectors.toMap(ServerTask::getTaskId, serverTask -> serverTask, (k1, k2) -> k1));
            orderInfoVOList.forEach(orderInfoVO -> {
                ServerTask serverTask = taskMap.get(orderInfoVO.getTaskId());
                orderInfoVO.setTaskName(serverTask.getTaskName());
                orderInfoVO.setState(serverTask.getState());
                orderInfoVO.setStateName(TaskStateEnum.getByCodeToApp(serverTask.getState()));
                orderInfoVO.setOrderStatusName(OrderStatusEnum.getOrderStatusEnumByCodeToApp(orderInfoVO.getOrderStatus()));
                if (!Objects.isNull(userMap)) {
                    AppUser appUser = userMap.get(orderInfoVO.getOrderUserId());
                    orderInfoVO.setQqCode(appUser.getQqCode());
                    orderInfoVO.setMobile(appUser.getMobile());
                }
            });
        }
        return voPageInfo;
    }

    /**
     * 查询订单列表
     *
     * @param pageDTO 订单
     * @return 订单
     */
    @Override
    public PageInfo<OrderInfoAppVO> getOrderList(OrderInfoAppPageDTO pageDTO) {
        if (null != pageDTO.getOrderStatus()) {
            Boolean exist = OrderStatusAppEnum.isExist(pageDTO.getOrderStatus());
            if (!exist) {
                throw new ServiceException("非法的订单状态类型");
            }
            pageDTO.setOrderStatusCode(OrderStatusEnum.getOrderStatusEnum(OrderStatusAppEnum.getOrderStatusEnumByCode(pageDTO.getOrderStatus())));
        }
        List<OrderInfo> orderList = orderInfoMapper.getOrderList(pageDTO);
        if (CollectionUtils.isEmpty(orderList)) {
            return new PageInfo<>();
        }
        PageInfo<OrderInfo> pageInfo = new PageInfo<>(orderList);
        PageInfo<OrderInfoAppVO> appVOPageInfo = PageUtils.copyPage(pageInfo, OrderInfoAppVO.class);
        Map<Long, String> stringMap = orderList.stream().collect(Collectors.toMap(OrderInfo::getOrderId, OrderInfo::getOrderSnapshot));
        List<OrderInfoAppVO> list = appVOPageInfo.getList();
        List<Long> taskIds = list.stream().map(OrderInfoAppVO::getTaskId).collect(Collectors.toList());
        List<ServerTask> serverTaskList = serverTaskService.selectServerTaskByTaskIds(taskIds);
        Map<Long, ServerTask> taskMap = serverTaskList.stream().collect(Collectors.toMap(ServerTask::getTaskId, serverTask -> serverTask, (k1, k2) -> k1));

        list.forEach(orderInfoAppVO -> {
            orderInfoAppVO.setOrderStatusName(OrderStatusEnum.getOrderStatusEnumByCodeToApp(orderInfoAppVO.getOrderStatus()));
            if (!CollectionUtils.isEmpty(stringMap)) {
                String orderSnapshot = stringMap.get(orderInfoAppVO.getOrderId());
                OrderInfoSnapshotDTO orderInfoSnapshotDTO = JSON.parseObject(orderSnapshot, OrderInfoSnapshotDTO.class);
                AppUserAccountSnapshootDTO accountSnapshoot = orderInfoSnapshotDTO.getAccountSnapshoot();
                if (!Objects.isNull(taskMap)) {
                    orderInfoAppVO.setTaskName(taskMap.get(orderInfoAppVO.getTaskId()).getTaskName());
                    orderInfoAppVO.setTaskState(taskMap.get(orderInfoAppVO.getTaskId()).getState());
                    orderInfoAppVO.setTaskStateName(TaskStateEnum.getByCodeToApp(taskMap.get(orderInfoAppVO.getTaskId()).getState()));
                }
                orderInfoAppVO.setAccount(accountSnapshoot.getAccount());
                orderInfoAppVO.setRoleId(accountSnapshoot.getRoleId());
                orderInfoAppVO.setRoleName(accountSnapshoot.getRoleName());
                orderInfoAppVO.setSnapshotDTO(orderInfoSnapshotDTO);
            }
        });
        return appVOPageInfo;
    }

    /**
     * 下单
     *
     * @param orderInfoDTO 订单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String buyOrder(OrderInfoDTO orderInfoDTO, LoginAppUser loginAppUser) {
//        RLock lock = redisson.getLock(CacheConstants.ORDER_LOCK_KEY + loginAppUser.getAppUser().getUserId() + "_" + orderInfoDTO.getTaskId().toString());
//        try {
//            lock.lock(10, TimeUnit.SECONDS);
        log.info("下单参数：{}", orderInfoDTO);
        log.info("下单人：{}", loginAppUser.getAppUser());

        OrderInfo orderInfo = BeanUtil.copyProperties(orderInfoDTO, OrderInfo.class);
        //校验数据
        cheakData(orderInfo, loginAppUser);

        Date nowDate = DateUtils.getNowDate();
        orderInfo.setOrderId(IdWorker.getId());
        //生成订单编号
        orderInfo.setOrderNum(OrderIdGenerator.generateOrderId(orderInfo.getOrderId()));
        orderInfo.setOrderTime(nowDate);
        orderInfo.setOrderUserId(loginAppUser.getUserId());
        orderInfo.setOrderUserName(loginAppUser.getAppUser().getUserName());
        orderInfo.setCreateBy(loginAppUser.getAppUser().getUserName());
        orderInfo.setCreateTime(nowDate);
        orderInfo.setOrderTimeOut(DateUtil.offsetMinute(nowDate, orderTimeOut));
        orderInfo.setOrderStatus(OrderStatusEnum.WAIT_PAY.getCode());

        //生成订单快照
        OrderInfoSnapshotDTO orderInfoSnapshot = generateSnapshot(orderInfo, loginAppUser.getAppUser());
        orderInfo.setOrderSnapshot(JSON.toJSONString(orderInfoSnapshot));
        int i = orderInfoMapper.insertOrderInfo(orderInfo);
        if (i > 0) {
            log.info("触发超时取消订单mq,订单id:{}", orderInfo.getOrderId());
            //TODO 触发超时取消订单mq
//            sendMsg.sendMsg(JSON.toJSONString(orderInfo), 5000);
        }
        return orderInfo.getOrderNum();
//        } catch (Exception e) {
//            // 处理被中断的情况（例如，记录日志或恢复中断状态）
//        } finally {
//            if (lock.isHeldByCurrentThread()) {
//                lock.unlock();
//            }
//        }
//        return 0;
    }

    /**
     * 生成订单
     *
     * @param orderInfo
     * @return
     */
    private OrderInfoSnapshotDTO generateSnapshot(OrderInfo orderInfo, AppUser appUser) {
        //订单快照
        OrderInfoSnapshotDTO orderInfoSnapshot = BeanUtil.copyProperties(orderInfo, OrderInfoSnapshotDTO.class);
        //区服任务快照
        ServerTaskVO serverTask = serverTaskService.selectServerTaskByTaskId(orderInfo.getTaskId());
        ServerTaskSnapshootDTO serverTaskSnapshootDTO = BeanUtil.copyProperties(serverTask, ServerTaskSnapshootDTO.class);
        serverTaskSnapshootDTO.setStateName(TaskStateEnum.getByCodeToApp(serverTask.getState()));
        orderInfoSnapshot.setTaskSnapshoot(serverTaskSnapshootDTO);
        //账号快照
        AppUserAccount userAccount = appUserAccountService.getUserAccountByUserIdAndAccountId(orderInfo.getOrderUserId(), orderInfo.getAccountId());
        AppUserAccountSnapshootDTO appUserAccountSnapshootDTO = BeanUtil.copyProperties(userAccount, AppUserAccountSnapshootDTO.class);
        orderInfoSnapshot.setAccountSnapshoot(appUserAccountSnapshootDTO);
        //用户快照
        AppUserSnapshootDTO snapshootDTO = BeanUtil.copyProperties(appUser, AppUserSnapshootDTO.class);
        orderInfoSnapshot.setAppUserSnapshoot(snapshootDTO);
        return orderInfoSnapshot;
    }

    @Override
    public Map<String, String> payOrder(String orderNum, String ip, AppUser appUser) {
        log.info("订单编号: {}, 发起人IP: {}, 用户openid: {}", orderNum, ip, appUser.getOpenId());
        OrderInfo orderInfo = orderInfoMapper.getOrderInfoByOrderNum(orderNum);
        if (Objects.isNull(orderInfo)) {
            throw new ServiceException("该订单号不存在");
        }
        if (!appUser.getUserId().equals(orderInfo.getOrderUserId())) {
            throw new ServiceException("当前订单不是当前登录用户的, 请重新登录尝试");
        }
        //价格
        BigDecimal orderPrice = orderInfo.getOrderPrice();
        OrderInfoSnapshotDTO orderInfoSnapshotDTO = JSON.parseObject(orderInfo.getOrderSnapshot(), OrderInfoSnapshotDTO.class);
        /**
         * https://blog.51cto.com/u_14125/9818133
         */
        log.info("回调地址: {}", wxPayConfig.getNotifyUrl());
        Map<String, String> params = JsApiOrderModel
                .builder()
                .appid(wxPayConfig.getAppId())
                .mch_id(wxPayConfig.getMchId())
                // 随机字符串
                .nonce_str(orderInfo.getOrderNum())
                .body("珊珊开团")
                // 订单号
                .out_trade_no(orderInfo.getOrderNum())
                // 支付金额注意是以分为单位的
                .total_fee(String.valueOf((orderPrice.multiply(new BigDecimal("100"))).intValue()))
                //发起订单者ip
                .spbill_create_ip(ip)
                .notify_url(wxPayConfig.getNotifyUrl())
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(appUser.getOpenId())
                .build()
                .createSign(wxPayConfig.getMchKey(), SignType.MD5);
        //进行数据加密封装
        String xmlResult = WxPayApi.pushOrder(false, params);
        Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
        log.info("微信统一支付接口结果: {}", JSON.toJSONString(resultMap));
        if (StringUtils.equals(resultMap.get("return_code"), "SUCCESS")) {
            String prepayId = resultMap.get("prepay_id");
            Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepayId, wxPayConfig.getAppId(),
                    wxPayConfig.getMchKey(), SignType.MD5);
            // 微信浏览器中拿此参数调起支付
            return packageParams;
        }
        return null;
    }

    /**
     * 校验订单
     *
     * @param orderInfo
     */
    private void cheakData(OrderInfo orderInfo, LoginAppUser loginAppUser) {
        Long taskId = orderInfo.getTaskId();
        ServerTaskVO serverTask = serverTaskService.selectServerTaskByTaskId(taskId);
        if (Objects.isNull(serverTask)) {
            throw new ServiceException("报名不存在，请刷新后尝试");
        }
        orderInfo.setRegionId(serverTask.getRegionId());

        List<TaskStateEnum> stateEnums = Arrays.asList(TaskStateEnum.DRAFT);
        if (stateEnums.contains(serverTask.getState())) {
            throw new ServiceException("报名不存在，请刷新后尝试");
        }
        if (TaskStateEnum.COMPLETE.getCode().equals(serverTask.getState())) {
            throw new ServiceException("报名已结束");
        }

        if (serverTask.getDiscountPrice() != null && serverTask.getDiscountPrice().compareTo(orderInfo.getOrderPrice()) != 0) {
            throw new ServiceException("前台传入订单金额与后台金额不一致");
        }

        if (serverTask.getDiscountPrice() == null && serverTask.getPrice().compareTo(orderInfo.getOrderPrice()) != 0) {
            throw new ServiceException("前台传入订单金额与后台金额不一致");
        }

        AppUserAccount userAccount = appUserAccountService.getUserAccountByUserIdAndAccountId(loginAppUser.getAppUser().getUserId(), orderInfo.getAccountId());
        if (Objects.isNull(userAccount)) {
            throw new ServiceException("该游戏账号不存在，请刷新后尝试");
        }
        orderInfo.setAccount(userAccount.getAccount());

        //判断是否购买了
        Long count = orderInfoMapper.selectCount(new QueryWrapper<OrderInfo>().lambda()
                .eq(OrderInfo::getTaskId, orderInfo.getTaskId())
                .eq(OrderInfo::getAccountId, orderInfo.getAccountId())
                .in(OrderInfo::getOrderStatus, Arrays.asList(OrderStatusEnum.PAID.getCode(), OrderStatusEnum.FINISH.getCode()))
        );
        if (count > 0) {
            throw new ServiceException("您已报名，请勿重复报名");
        }

        Long selectCount = orderInfoMapper.selectCount(new QueryWrapper<OrderInfo>().lambda()
                .eq(OrderInfo::getTaskId, orderInfo.getTaskId())
                .eq(OrderInfo::getAccountId, orderInfo.getAccountId())
                .eq(OrderInfo::getOrderStatus, OrderStatusEnum.WAIT_PAY.getCode())
        );
        if (selectCount > 0) {
            throw new ServiceException("您已下单，待支付，请勿重复报名");
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cancelOrder(LoginAppUser loginAppUser, String orderNum) {
        OrderInfo orderInfo = orderInfoMapper.getOrderInfoByOrderNum(orderNum);
        if (Objects.isNull(orderInfo)) {
            throw new ServiceException("订单不存在");
        }
        if (!loginAppUser.getUserId().equals(orderInfo.getOrderUserId())) {
            throw new ServiceException("当前订单不是当前登录人的订单，请重新登录后尝试");
        }
        List<Integer> list = Arrays.asList(OrderStatusEnum.PAID.getCode(), OrderStatusEnum.FINISH.getCode());
        if (list.contains(orderInfo.getOrderStatus())) {
            throw new ServiceException("当前订单状态不能取消订单");
        }
        OrderInfo thisOrder = new OrderInfo();
        thisOrder.setOrderId(orderInfo.getOrderId());
        thisOrder.setCancelOrderTime(DateUtils.getNowDate());
        thisOrder.setOrderStatus(OrderStatusEnum.CANCEL_ORDER.getCode());
        thisOrder.setUpdateBy(loginAppUser.getAppUser().getUserName());
        thisOrder.setUpdateTime(new Date());
        int update = orderInfoMapper.update(null, new UpdateWrapper<OrderInfo>()
                .lambda()
                .set(OrderInfo::getCancelOrderTime, DateUtils.getNowDate())
                .set(OrderInfo::getOrderStatus, OrderStatusEnum.CANCEL_ORDER.getCode())
                .set(OrderInfo::getUpdateTime, DateUtils.getNowDate())
                .set(OrderInfo::getUpdateBy, loginAppUser.getAppUser().getUserName())
                .eq(OrderInfo::getOrderId, orderInfo.getOrderId())
        );
        return update;
    }

    /**
     * 批量删除订单
     *
     * @param orderIds 需要删除的订单主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteOrderInfoByOrderIds(Long[] orderIds) {
        return orderInfoMapper.deleteOrderInfoByOrderIds(orderIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int userRemoveByIds(LoginAppUser loginAppUser, Long[] orderIds) {
        List<OrderInfo> orderInfos = orderInfoMapper.selectOrderInfoByOrderIds(orderIds);
        orderInfos.forEach(orderInfo -> {
            if (!loginAppUser.getAppUser().getUserId().equals(orderInfo.getOrderUserId())) {
                throw new ServiceException("请选择自己的订单");
            }
        });
        return orderInfoMapper.userRemoveByIds(orderIds);
    }

    /**
     * 删除订单信息
     *
     * @param orderId 订单主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteOrderInfoByOrderId(Long orderId) {
        return orderInfoMapper.deleteOrderInfoByOrderId(orderId);
    }

    @Override
    public List<ServerTaskPeopleCountVO> getApplyPeopleCountByTaskIds(List<Long> taskIds) {
        return orderInfoMapper.getApplyPeopleCountByTaskIds(taskIds);
    }

    @Override
    public ServerTaskPeopleCountVO getApplyPeopleCountByTaskId(Long taskId) {
        return orderInfoMapper.getApplyPeopleCountByTaskId(taskId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderByTaskId(Long taskId, OrderStatusEnum orderStatusEnum) {
        switch (orderStatusEnum) {
            case UNDER_WAY:
                //修改订单状态为进行中
                orderInfoMapper.update(null, new UpdateWrapper<OrderInfo>()
                        .lambda()
                        .set(OrderInfo::getOrderStatus, OrderStatusEnum.UNDER_WAY.getCode())
                        .set(OrderInfo::getOrderBeginTime, DateUtils.getNowDate())
                        .eq(OrderInfo::getTaskId, taskId)
                        .eq(OrderInfo::getOrderStatus, OrderStatusEnum.PAID.getCode())
                );
                break;
            case FINISH:
                //修改订单状态为已完成
                orderInfoMapper.update(null, new UpdateWrapper<OrderInfo>()
                        .lambda()
                        .set(OrderInfo::getOrderStatus, OrderStatusEnum.FINISH.getCode())
                        .set(OrderInfo::getOrderFinishTime, DateUtils.getNowDate())
                        .eq(OrderInfo::getTaskId, taskId)
                        .eq(OrderInfo::getOrderStatus, OrderStatusEnum.UNDER_WAY.getCode())
                );
                break;
            default:
                throw new RuntimeException("订单状态异常");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrderTask() {
        //查询所有未付款的并超时的订单
        List<OrderInfo> orderInfoList = orderInfoMapper.getUnpaidAndTimeoutOrders();
        log.info("查询所有未付款的并超时的订单: {}", JSON.toJSONString(orderInfoList));
        if (CollectionUtils.isNotEmpty(orderInfoList)) {
            //批量修改订单为系统取消订单
            List<Long> orderIds = orderInfoList.stream().map(OrderInfo::getOrderId).collect(Collectors.toList());
            orderInfoMapper.update(null, new UpdateWrapper<OrderInfo>()
                    .lambda()
                    .set(OrderInfo::getOrderStatus, OrderStatusEnum.TIMEOUT_CANCEL_ORDER.getCode())
                    .in(OrderInfo::getOrderId, orderIds)
            );
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String parseOrderNotifyResult(Map<String, String> resultMap) {
        String orderNum = resultMap.get("out_trade_no");
        log.info("微信回调订单号: {}", orderNum);
        OrderInfo orderInfo = orderInfoMapper.getOrderInfoByOrderNum(orderNum);
        if (Objects.isNull(orderInfo)) {
            return "FAIL";
        }
        List<Integer> integers = Arrays.asList(OrderStatusEnum.PAID.getCode(), OrderStatusEnum.FINISH.getCode());
        if (integers.contains(orderInfo.getOrderStatus())) {
            log.info("微信重复回调, 完成订单号: {}", orderNum);
            return "SUCCESS";
        }
        //订单总金额，单位为分
        String totalFee = resultMap.get("total_fee");
        BigDecimal payAmount = new BigDecimal(Integer.valueOf(totalFee)).divide(BigDecimal.valueOf(100));
        Date date = new Date();
        //修改订单状态
        orderInfo.setOrderStatus(OrderStatusEnum.PAID.getCode());
        orderInfo.setPayTime(date);
        orderInfo.setPayAmount(payAmount);
        int update = orderInfoMapper.update(null, new UpdateWrapper<OrderInfo>()
                .lambda()
                .set(OrderInfo::getOrderStatus, OrderStatusEnum.PAID.getCode())
                .set(OrderInfo::getPayTime, date)
                .set(OrderInfo::getPayAmount, payAmount)
                .eq(OrderInfo::getOrderNum, orderInfo.getOrderNum())
        );
        if (update > 0) {
            log.info("微信回调完成订单号: {}", orderNum);
            return "SUCCESS";
        }
        return "FAIL";
    }

    @Override
    public List<OrderInfo> getOrderInfoListByTaskIdsAndUserId(List<Long> taskIds, Long userId) {
        return orderInfoMapper.getOrderInfoListByTaskIdsAndUserId(taskIds, userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int manualPay(OrderManualPayDTO payDTO) {
        OrderInfo orderInfo = orderInfoMapper.selectOrderInfoByOrderId(payDTO.getOrderId());
        if (Objects.isNull(orderInfo)) {
            throw new ServiceException("订单不存在");
        }
        List<Integer> list = Arrays.asList(OrderStatusEnum.CANCEL_ORDER.getCode(), OrderStatusEnum.TIMEOUT_CANCEL_ORDER.getCode());
        if (list.contains(orderInfo.getOrderStatus())) {
            throw new ServiceException("订单已取消");
        }
        if (!OrderStatusEnum.WAIT_PAY.getCode().equals(orderInfo.getOrderStatus())) {
            throw new ServiceException("仅待支付状态下进行修改");
        }
        int update = orderInfoMapper.update(null, new UpdateWrapper<OrderInfo>()
                .lambda()
                .set(OrderInfo::getPayAmount, payDTO.getPayAmount())
                .set(OrderInfo::getPayTime, DateUtils.getNowDate())
                .set(OrderInfo::getOrderStatus, OrderStatusEnum.PAID.getCode())
                .eq(OrderInfo::getOrderId, orderInfo.getOrderId())
        );
        return update;
    }

    @Override
    public List<OrderInfo> selectOrderInfoListByTaskId(Long taskId) {
        return orderInfoMapper.selectOrderInfoListByTaskId(taskId);
    }
}
